#include "Marshal2.h"
#include <msclr/marshal.h>

using namespace System::Runtime::InteropServices;
using namespace System;

namespace Ws2Com {
	/*String^
		Marshal::UTF8CStringToClrString(const char* str) {
		wchar_t* strUtf16 = reinterpret_cast<wchar_t*> (g_utf8_to_utf16(str, -1, NULL, NULL, NULL));
		String^ result = gcnew String(strUtf16);
		g_free(strUtf16);
		return result;
	}*/

	//char*
	//	Marshal::ClrStringToUTF8CString(String^ str) {
	//	msclr::interop::marshal_context^ context = gcnew msclr::interop::marshal_context();
	//	const wchar_t* strUtf16 = context->marshal_as<const wchar_t*>(str);
	//	//gchar* strUtf8 = g_utf16_to_utf8(reinterpret_cast<const gunichar2*> (strUtf16), -1, NULL, NULL, NULL);
	//	//gchar* strUtf8 = g_utf16_to_utf8(strUtf16);
	//	delete context;
	//	return strUtf8;
	//}

	String^ Marshal2::UTF8CStringToClrString(const char* str) {
		//wchar_t* strUtf16 = reinterpret_cast<wchar_t*> (g_utf8_to_utf16(str, -1, NULL, NULL, NULL));
		String^ result = gcnew String(str);
		//g_free(strUtf16);
		return result;
	}


	char* Marshal2::ClrStringToUTF8CString(System::String^ str) {
		char* d = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
		return d;
	}

	array<unsigned char>^ Marshal2::UTF8CharToClrArrayChar(std::string str) {
		array<unsigned char>^ buffer = gcnew array<unsigned char>(str.length());
		char* ptr = &str[0];
		Marshal::Copy(IntPtr(ptr), buffer, 0, buffer->Length);
		return buffer;
	}

	std::string Marshal2::ansi_to_utf8(std::string strAnsi) {
		UINT nLen = MultiByteToWideChar(936, NULL, strAnsi.c_str(), -1, NULL, NULL);
		WCHAR* wszBuffer = new WCHAR[nLen + 1];
		nLen = MultiByteToWideChar(936, NULL, strAnsi.c_str(), -1, wszBuffer, nLen);
		wszBuffer[nLen] = 0;
		nLen = WideCharToMultiByte(CP_UTF8, NULL, wszBuffer, -1, NULL, NULL, NULL, NULL);
		CHAR* szBuffer = new CHAR[nLen + 1];
		nLen = WideCharToMultiByte(CP_UTF8, NULL, wszBuffer, -1, szBuffer, nLen, NULL, NULL);
		szBuffer[nLen] = 0;
		strAnsi = szBuffer;
		delete[]wszBuffer;
		delete[]szBuffer;
		return strAnsi;
	}

	std::string Marshal2::utf8_to_ansi(std::string strUTF8) {
		UINT nLen = MultiByteToWideChar(CP_UTF8, NULL, strUTF8.c_str(), -1, NULL, NULL);
		WCHAR* wszBuffer = new WCHAR[nLen + 1];
		nLen = MultiByteToWideChar(CP_UTF8, NULL, strUTF8.c_str(), -1, wszBuffer, nLen);
		wszBuffer[nLen] = 0;
		nLen = WideCharToMultiByte(936, NULL, wszBuffer, -1, NULL, NULL, NULL, NULL);
		CHAR* szBuffer = new CHAR[nLen + 1];
		nLen = WideCharToMultiByte(936, NULL, wszBuffer, -1, szBuffer, nLen, NULL, NULL);
		szBuffer[nLen] = 0;
		strUTF8 = szBuffer;
		delete[]szBuffer;
		delete[]wszBuffer;
		return strUTF8;
	}

	//----------------------------------------------------------------------------
	// FUNCTION: ConvertUTF16ToUTF8
	// DESC: Converts Unicode UTF-16 (Windows default) text to Unicode UTF-8.
	//----------------------------------------------------------------------------
//	gchar* g_utf16_to_utf8(__in const wchar_t* pszTextUTF16) {
//		//
//		// Special case of NULL or empty input string
//		//
//		if ((pszTextUTF16 == NULL) || (*pszTextUTF16 == L'\0')) {
//			// Return empty string
//			return "";
//		}
//
//		//
//		// Consider WCHAR's count corresponding to total input string length,
//		// including end-of-string (L'\0') character.
//		//
//		const size_t cchUTF16Max = INT_MAX - 1;
//		size_t cchUTF16;
//		HRESULT hr = ::StringCchLengthW(pszTextUTF16, cchUTF16Max, &cchUTF16);
//
//		if (FAILED(hr)) {
//			AtlThrow(hr);
//		}
//
//		// Consider also terminating \0
//		++cchUTF16;
//
//		//
//		// WC_ERR_INVALID_CHARS flag is set to fail if invalid input character
//		// is encountered.
//		// This flag is supported on Windows Vista and later.
//		// Don't use it on Windows XP and previous.
//		//
//
//#if (WINVER >= 0x0600)
//		DWORD dwConversionFlags = WC_ERR_INVALID_CHARS;
//#else
//		DWORD dwConversionFlags = 0;
//#endif
//
//		//
//		// Get size of destination UTF-8 buffer, in CHAR's (= bytes)
//		//
//		int cbUTF8 = ::WideCharToMultiByte(
//			CP_UTF8,                // convert to UTF-8
//			dwConversionFlags,      // specify conversion behavior
//			pszTextUTF16,           // source UTF-16 string
//			static_cast<int>(cchUTF16),   // total source string length, in WCHAR's,
//											// including end-of-string \0
//			NULL,                   // unused - no conversion required in this step
//			0,                      // request buffer size
//			NULL, NULL              // unused
//		);
//
//		ATLASSERT(cbUTF8 != 0);
//
//		if (cbUTF8 == 0) {
//			AtlThrowLastWin32();
//		}
//
//		//
//		// Allocate destination buffer for UTF-8 string
//		//
//		CStringA strUTF8;
//		int cchUTF8 = cbUTF8; // sizeof(CHAR) = 1 byte
//		CHAR* pszUTF8 = strUTF8.GetBuffer(cchUTF8);
//
//		//
//		// Do the conversion from UTF-16 to UTF-8
//		//
//		int result = ::WideCharToMultiByte(
//			CP_UTF8,                // convert to UTF-8
//			dwConversionFlags,      // specify conversion behavior
//			pszTextUTF16,           // source UTF-16 string
//			static_cast<int>(cchUTF16),   // total source string length, in WCHAR's,
//											// including end-of-string \0
//			pszUTF8,                // destination buffer
//			cbUTF8,                 // destination buffer size, in bytes
//			NULL, NULL              // unused
//		);
//
//		ATLASSERT(result != 0);
//
//		if (result == 0) {
//			AtlThrowLastWin32();
//		}
//
//		// Release internal CString buffer
//		strUTF8.ReleaseBuffer();
//
//		// Return resulting UTF-8 string
//		return strUTF8;
//	}
}